#include "contact_system.h"

// 初始化双向循环链表 - 创建头节点并形成循环
ContactNode* initList() {
    ContactNode *head = (ContactNode*)malloc(sizeof(ContactNode));
    if (!head) {
        printf("内存分配失败！\n");
        return NULL;
    }
    
    // 头节点不存储有效数据，只需要建立循环结构
    head->prior = head;
    head->next = head;
    
    return head;
}

// 检查链表是否为空（只有头节点）
int isEmpty(ContactNode *head) {
    return head->next == head;
}

// 创建新数据节点
ContactNode* createNode(int id, const char *name, char gender, const char *phone) {
    ContactNode *newNode = (ContactNode*)malloc(sizeof(ContactNode));
    if (!newNode) {
        printf("内存分配失败！\n");
        return NULL;
    }
    
    newNode->id = id;
    strncpy(newNode->name, name, MAX_NAME - 1);
    newNode->name[MAX_NAME - 1] = '\0';
    newNode->gender = toupper(gender);
    strncpy(newNode->phone, phone, MAX_PHONE - 1);
    newNode->phone[MAX_PHONE - 1] = '\0';
    newNode->prior = NULL;
    newNode->next = NULL;
    
    return newNode;
}

// 获取链表长度（不包括头节点）
int getLength(ContactNode *head) {
    int count = 0;
    ContactNode *current = head->next;
    
    while (current != head) {
        count++;
        current = current->next;
    }
    return count;
}

// 添加联系人到链表末尾
void addContact(ContactNode *head) {
    int id;
    char name[MAX_NAME], phone[MAX_PHONE];
    char gender;
    
    printf("\n--- 添加联系人 ---\n");
    printf("请输入编号: ");
    scanf("%d", &id);
    printf("请输入姓名: ");
    scanf("%s", name);
    printf("请输入性别(M/F): ");
    scanf(" %c", &gender);
    printf("请输入电话: ");
    scanf("%s", phone);
    
    // 输入验证
    if (id <= 0) {
        printf("错误：编号必须大于0！\n");
        return;
    }
    if (gender != 'M' && gender != 'm' && gender != 'F' && gender != 'f') {
        printf("错误：性别必须是 M 或 F！\n");
        return;
    }
    
    // 检查编号是否已存在
    if (findContactById(head, id) != NULL) {
        printf("错误：编号 %d 已存在！\n", id);
        return;
    }
    
    ContactNode *newNode = createNode(id, name, gender, phone);
    if (!newNode) return;
    
    // 在头节点之前插入（即链表末尾）
    // 因为双向循环链表的头节点的prior指向尾节点
    newNode->next = head;
    newNode->prior = head->prior;
    head->prior->next = newNode;
    head->prior = newNode;
    
    printf("联系人添加成功！\n");
}

// 在指定位置插入联系人（位置从1开始）
void insertContactAtPosition(ContactNode *head, int position) {
    int length = getLength(head);
    if (position < 1 || position > length + 1) {
        printf("错误：位置无效！有效范围: 1-%d\n", length + 1);
        return;
    }
    
    int id;
    char name[MAX_NAME], phone[MAX_PHONE];
    char gender;
    
    printf("\n--- 插入联系人（位置 %d）---\n", position);
    printf("请输入编号: ");
    scanf("%d", &id);
    printf("请输入姓名: ");
    scanf("%s", name);
    printf("请输入性别(M/F): ");
    scanf(" %c", &gender);
    printf("请输入电话: ");
    scanf("%s", phone);
    
    // 检查编号是否已存在
    if (findContactById(head, id) != NULL) {
        printf("错误：编号 %d 已存在！\n", id);
        return;
    }
    
    ContactNode *newNode = createNode(id, name, gender, phone);
    if (!newNode) return;
    
    // 找到插入位置的前一个节点
    ContactNode *current = head;
    for (int i = 0; i < position - 1; i++) {
        current = current->next;
    }
    
    // 插入新节点
    newNode->next = current->next;
    newNode->prior = current;
    current->next->prior = newNode;
    current->next = newNode;
    
    printf("联系人插入成功！\n");
}

// 根据姓名删除联系人
void deleteContactByName(ContactNode *head, const char *name) {
    if (isEmpty(head)) {
        printf("通讯录为空！\n");
        return;
    }
    
    ContactNode *current = head->next;
    int found = 0;
    
    while (current != head) {
        if (strcmp(current->name, name) == 0) {
            found = 1;
            
            // 调整前后指针
            current->prior->next = current->next;
            current->next->prior = current->prior;
            
            free(current);
            printf("联系人【%s】删除成功！\n", name);
            break;
        }
        current = current->next;
    }
    
    if (!found) {
        printf("未找到姓名为【%s】的联系人！\n", name);
    }
}

// 根据编号删除联系人
void deleteContactById(ContactNode *head, int id) {
    if (isEmpty(head)) {
        printf("通讯录为空！\n");
        return;
    }
    
    ContactNode *current = head->next;
    int found = 0;
    
    while (current != head) {
        if (current->id == id) {
            found = 1;
            
            // 调整前后指针
            current->prior->next = current->next;
            current->next->prior = current->prior;
            
            free(current);
            printf("编号为【%d】的联系人删除成功！\n", id);
            break;
        }
        current = current->next;
    }
    
    if (!found) {
        printf("未找到编号为【%d】的联系人！\n", id);
    }
}

// 根据姓名查找联系人
ContactNode* findContactByName(ContactNode *head, const char *name) {
    ContactNode *current = head->next;
    
    while (current != head) {
        if (strcmp(current->name, name) == 0) {
            return current;
        }
        current = current->next;
    }
    
    return NULL;
}

// 根据编号查找联系人
ContactNode* findContactById(ContactNode *head, int id) {
    ContactNode *current = head->next;
    
    while (current != head) {
        if (current->id == id) {
            return current;
        }
        current = current->next;
    }
    
    return NULL;
}

// 修改联系人信息
void updateContact(ContactNode *head, const char *name) {
    ContactNode *target = findContactByName(head, name);
    
    if (target == NULL) {
        printf("未找到姓名为【%s】的联系人！\n", name);
        return;
    }
    
    int choice;
    printf("\n--- 修改联系人【%s】---\n", name);
    printf("当前信息: ID:%d, 姓名:%s, 性别:%c, 电话:%s\n", 
           target->id, target->name, target->gender, target->phone);
    
    printf("\n请选择要修改的内容:\n");
    printf("1. 编号\n2. 姓名\n3. 性别\n4. 电话\n5. 全部修改\n");
    printf("请选择(1-5): ");
    scanf("%d", &choice);
    
    switch(choice) {
        case 1:
            printf("请输入新编号: ");
            scanf("%d", &target->id);
            break;
        case 2:
            printf("请输入新姓名: ");
            scanf("%s", target->name);
            break;
        case 3:
            printf("请输入新性别(M/F): ");
            scanf(" %c", &target->gender);
            target->gender = toupper(target->gender);
            break;
        case 4:
            printf("请输入新电话: ");
            scanf("%s", target->phone);
            break;
        case 5:
            printf("请输入新编号: ");
            scanf("%d", &target->id);
            printf("请输入新姓名: ");
            scanf("%s", target->name);
            printf("请输入新性别(M/F): ");
            scanf(" %c", &target->gender);
            target->gender = toupper(target->gender);
            printf("请输入新电话: ");
            scanf("%s", target->phone);
            break;
        default:
            printf("无效选择！\n");
            return;
    }
    
    printf("修改成功！\n");
}

// 正向遍历显示所有联系人
void showContacts(ContactNode *head) {
    if (isEmpty(head)) {
        printf("通讯录为空！\n");
        return;
    }
    
    ContactNode *current = head->next;
    printf("\n=== 通讯录列表（正向） ===\n");
    printf("┌─────┬──────────┬──────┬────────────┐\n");
    printf("│ %-4s│ %-8s   │ %-4s │ %-11s  │\n", "ID", "姓名", "性别", "电话");
    printf("├─────┼──────────┼──────┼────────────┤\n");
    
    while (current != head) {
        printf("│ %-4d│ %-8s │ %-4c │ %-11s│\n", 
               current->id, current->name, current->gender, current->phone);
        current = current->next;
    }
    printf("└─────┴──────────┴──────┴────────────┘\n");
    printf("总计: %d 个联系人\n", getLength(head));
}

// 反向遍历显示所有联系人
void showContactsReverse(ContactNode *head) {
    if (isEmpty(head)) {
        printf("通讯录为空！\n");
        return;
    }
    
    ContactNode *current = head->prior;
    printf("\n=== 通讯录列表（反向） ===\n");
    printf("┌─────┬──────────┬──────┬────────────┐\n");
    printf("│ %-4s│ %-8s   │ %-4s │ %-11s  │\n", "ID", "姓名", "性别", "电话");
    printf("├─────┼──────────┼──────┼────────────┤\n");
    
    while (current != head) {
        printf("│ %-4d│ %-8s │ %-4c │ %-11s│\n", 
               current->id, current->name, current->gender, current->phone);
        current = current->prior;
    }
    printf("└─────┴──────────┴──────┴────────────┘\n");
}

// 正向遍历（通用函数）
void traverseForward(ContactNode *head) {
    if (isEmpty(head)) {
        printf("通讯录为空！\n");
        return;
    }
    
    ContactNode *current = head->next;
    int count = 1;
    
    printf("\n正向遍历:\n");
    while (current != head) {
        printf("%d. ID:%d, 姓名:%s, 性别:%c, 电话:%s\n", 
               count++, current->id, current->name, current->gender, current->phone);
        current = current->next;
    }
}

// 反向遍历（通用函数）
void traverseBackward(ContactNode *head) {
    if (isEmpty(head)) {
        printf("通讯录为空！\n");
        return;
    }
    
    ContactNode *current = head->prior;
    int count = 1;
    
    printf("\n反向遍历:\n");
    while (current != head) {
        printf("%d. ID:%d, 姓名:%s, 性别:%c, 电话:%s\n", 
               count++, current->id, current->name, current->gender, current->phone);
        current = current->prior;
    }
}

// 统计性别分布
void countGender(ContactNode *head) {
    if (isEmpty(head)) {
        printf("通讯录为空！\n");
        return;
    }
    
    int male = 0, female = 0;
    ContactNode *current = head->next;
    
    while (current != head) {
        if (current->gender == 'M') {
            male++;
        } else if (current->gender == 'F') {
            female++;
        }
        current = current->next;
    }
    
    printf("\n=== 性别统计 ===\n");
    printf("男性: %d 人\n", male);
    printf("女性: %d 人\n", female);
    printf("总计: %d 人\n", male + female);
}

// 按姓名排序（冒泡排序）
void sortContactsByName(ContactNode *head) {
    int length = getLength(head);
    if (length <= 1) return;
    
    int swapped;
    ContactNode *ptr1;
    
    do {
        swapped = 0;
        ptr1 = head->next;
        
        while (ptr1->next != head) {
            if (strcmp(ptr1->name, ptr1->next->name) > 0) {
                // 交换节点数据
                swapNodeData(ptr1, ptr1->next);
                swapped = 1;
            }
            ptr1 = ptr1->next;
        }
    } while (swapped);
    
    printf("按姓名排序完成！\n");
}

// 交换两个节点的数据
void swapNodeData(ContactNode *a, ContactNode *b) {
    // 交换编号
    int tempId = a->id;
    a->id = b->id;
    b->id = tempId;
    
    // 交换姓名
    char tempName[MAX_NAME];
    strcpy(tempName, a->name);
    strcpy(a->name, b->name);
    strcpy(b->name, tempName);
    
    // 交换性别
    char tempGender = a->gender;
    a->gender = b->gender;
    b->gender = tempGender;
    
    // 交换电话
    char tempPhone[MAX_PHONE];
    strcpy(tempPhone, a->phone);
    strcpy(a->phone, b->phone);
    strcpy(b->phone, tempPhone);
}

// 清空链表（保留头节点）
void clearList(ContactNode *head) {
    if (isEmpty(head)) return;
    
    ContactNode *current = head->next;
    ContactNode *nextNode;
    
    while (current != head) {
        nextNode = current->next;
        free(current);
        current = nextNode;
    }
    
    // 重置头节点的指针
    head->next = head;
    head->prior = head;
    
    printf("通讯录已清空！\n");
}

// 释放整个链表（包括头节点）
void freeList(ContactNode *head) {
    if (!head) return;
    
    // 先释放所有数据节点
    clearList(head);
    
    // 再释放头节点
    free(head);
}
